package com.leo.apptest.activity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import com.leo.apptest.R;
import com.leo.apptest.event.AnnoTest;
import com.leo.apptest.event.EventTest;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class EventBusActivity extends AppCompatActivity {
    private static final String TAG = "EventBusActivity";
    private TextView mTvContent;
    private MyHandler mHandler ;
    private ExecutorService mExecutorService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_bus);
        EventBus.getDefault().register(this);
        mTvContent = (TextView) findViewById(R.id.tvContent);
        mTvContent.setText("sdasda\\nasdada");
        mHandler = new MyHandler(Looper.getMainLooper());
        mExecutorService = Executors.newCachedThreadPool();
        Method[] declaredMethods = this.getClass().getDeclaredMethods();
        for (final Method declaredMethod : declaredMethods) {
            final AnnoTest annotation = declaredMethod.getAnnotation(AnnoTest.class);
            if (annotation != null) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        toSubscription(declaredMethod,Looper.myLooper() == Looper.getMainLooper(),annotation.isMain());
                    }
                }).start();
            }
        }
    }

    private void toSubscription(Method method,boolean isCurrentThreadMain,boolean isNeedMain){
        if (isNeedMain) {
            if (isCurrentThreadMain) {
                invokeMethod(method);
            } else {
                Message message = mHandler.obtainMessage();
                message.obj = method;
                mHandler.sendMessage(message);
            }
        } else {
            if (isCurrentThreadMain) {
                mExecutorService.execute(new MyRunner(method));
            } else {
                invokeMethod(method);
            }
        }
    }

    private void invokeMethod(Method method){
        try {
            EventTest test = new EventTest("asda");
            method.invoke(this,test);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }


    @AnnoTest(isMain = true)
    public void lala(EventTest test){
        System.out.println(TAG +" "+Thread.currentThread().getName());
        System.out.println(TAG+" lala handle  "+test.getTest());
    }

    @Subscribe(threadMode = ThreadMode.POSTING,sticky = false,priority = 1)
    public void onEvent(EventTest test){
//        mTvContent.setText(Thread.currentThread().getName()+"  test == "+test.getTest());
    }

    private class MyHandler extends Handler {

        public MyHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Method method = (Method) msg.obj;
            invokeMethod(method);
        }
    }

    private class MyRunner implements Runnable {

        private Method method;

        public MyRunner(Method method) {
            this.method = method;
        }

        @Override
        public void run() {
            invokeMethod(method);
        }
    }



}
